-module(test_aleph_dht_rpc).
-include("aleph_data_interface.hrl").
-include_lib("eunit/include/eunit.hrl"). 

%%
%% Exported Functions
%%
-export([response/2,store/2,error/2,send_result/2,do_actions/2,
         send_test/0,simple_message_test/0,lots_of_message_test/0,time_out_test/0]).
-import(aleph_dht_rpc,[send/3]).
%%
%% API Functions
%% 
do_actions(Fun,Args)->
    %io:format("do_actions~n"),  
    apply(test_aleph_dht_rpc,Fun,Args).

response(Expected_Msg,Msg)->
    %io:format("expected_response ~p get response ~p~n",[Expected_Msg,Msg]),  
    ?match(true,string:equal(Msg,Expected_Msg)).
  
store(_,Msg)->
    Response_msg="store got msg:"++Msg,
    %io:format("store msg:~p~n",[Response_msg]),
    aleph_dht_rpc:protocol(rsp,response,Response_msg).
   


error(Expected_Msg,Msg)->
    response(Expected_Msg,Msg).
send_result(Expected_Msg,Msg)->
     response(Expected_Msg,Msg).

send_test()->          
      {ok,S}=gen_udp:open(9877,[binary]),
      try
        send("127.0.0.1",9877,aleph_dht_rpc:protocol(rsp,send_result,"do echo")),   
        get_repsone("do echo")
      after
        gen_udp:close(S)
      end.

simple_message_test()->
      {ok,S}=gen_udp:open(9877,[binary]),
      try
        gen_udp:send(S,"127.0.0.1",9876,
        term_to_binary(protocol:new(req,store,["do store"],1,1))), 
        get_repsone("store got msg:do store")        
      after
       gen_udp:close(S) 
      end.

lots_of_message_test()->
    {ok,S}=gen_udp:open(9877,[binary]),
      try
        lists:foreach(fun(_)->
        gen_udp:send(S,"127.0.0.1",9876,
        term_to_binary(protocol:new(req,store,["do store"],1,1))),
        get_repsone("store got msg:do store")
        end,lists:seq(1,100))                                               
      after
       gen_udp:close(S) 
      end.
    
time_out_test()->          
      {ok,S}=gen_udp:open(9877,[binary]),
      try
       {_,Timer}=send("127.0.0.1",9877,
                      aleph_dht_rpc:protocol(rsp,send_result,"do echo")), 
        get_repsone("do echo"),
        timer:sleep(6*1000),
        gen_udp:send(S,"127.0.0.1",9876,       
        term_to_binary(protocol:new(rsp,store,["do store"],Timer,1))),
        get_repsone("message timer is expired")
      after
        gen_udp:close(S)
      end.                             
%%
%% Local Functions
%%
get_repsone(Expected_Msg)->
    receive 
        {udp,_,_,_,Packet}-> 
             #protocol{typ=Typ,args=Args,method=Fun,timer=_}=binary_to_term(Packet),
             %io:format("get_repsone msg:~p,Exp~p~n",[Args,Expected_Msg]),
             case Typ of
                 err->
                      [H|_]=Args,
                      error(Expected_Msg,H);
                 _->                      
                      apply(test_aleph_dht_rpc,Fun,[Expected_Msg|Args])
             end
        after 5000->
            io:format("test time out~n"),
            ?match(true,false)
    end.
 
   